<template>
  <div class="tui-scrollbar" :class="{
    'tui-scrollbar--horizontal': showHorizontal,
    'tui-scrollbar--vertical': showVertical,
    'tui-scrollbar--always-visible': props.visibilityMode === 'always'
  }" :style="containerStyle as Record<string, string>">
    <!-- 滚动内容容器 -->
    <div ref="scrollContainer" class="tui-scrollbar__container" :style="scrollContainerStyle as Record<string, string>" @scroll="handleScroll">
      <div class="tui-scrollbar__content" :style="contentPaddingStyle">
        <slot></slot>
      </div>
    </div>

    <!-- 自定义垂直滚动条 -->
    <div v-if="showVertical && needVerticalScrollbar" ref="verticalTrack" class="tui-scrollbar__track tui-scrollbar__track--vertical" @mousedown="handleTrackMouseDown('vertical')" :style="{ backgroundColor: props.trackColor, width: ensureUnit(effectiveTrackWidth, 'px') }">
      <div ref="verticalThumb" class="tui-scrollbar__thumb tui-scrollbar__thumb--vertical" :style="{
        width: ensureUnit(effectiveThumbWidth, 'px'),
        height: verticalThumbHeight,
        top: verticalThumbTop
      }" @mousedown="handleThumbMouseDown('vertical')" @mouseenter="handleThumbMouseEnter('vertical')" @mouseleave="handleThumbMouseLeave('vertical')">
        <!-- 垂直滚动条滑块自定义插槽 - 传递滚动进度和滚动方向 -->
        <slot name="verticalThumb" :progress="verticalScrollProgress" :direction="scrollDirection.vertical">
          <!-- 默认滑块样式 -->
          <div class="tui-scrollbar__thumb-inner" :style="{
            backgroundColor: verticalThumbColor,
            borderRadius: ensureUnit(props.borderRadius, 'px'),
            width: '100%',
            height: '100%'
          }"></div>
        </slot>
      </div>
    </div>

    <!-- 自定义水平滚动条 -->
    <div v-if="showHorizontal && needHorizontalScrollbar" ref="horizontalTrack" class="tui-scrollbar__track tui-scrollbar__track--horizontal" @mousedown="handleTrackMouseDown('horizontal')" :style="{ backgroundColor: props.trackColor, height: ensureUnit(effectiveTrackWidth, 'px') }">
      <div ref="horizontalThumb" class="tui-scrollbar__thumb tui-scrollbar__thumb--horizontal" :style="{
        height: ensureUnit(effectiveThumbWidth, 'px'),
        width: horizontalThumbWidth,
        left: horizontalThumbLeft
      }" @mousedown="handleThumbMouseDown('horizontal')" @mouseenter="handleThumbMouseEnter('horizontal')" @mouseleave="handleThumbMouseLeave('horizontal')">
        <!-- 水平滚动条滑块自定义插槽 - 传递滚动进度和滚动方向 -->
        <slot name="horizontalThumb" :progress="horizontalScrollProgress" :direction="scrollDirection.horizontal">
          <!-- 默认滑块样式 -->
          <div class="tui-scrollbar__thumb-inner" :style="{
            backgroundColor: horizontalThumbColor,
            borderRadius: ensureUnit(props.borderRadius, 'px'),
            width: '100%',
            height: '100%'
          }"></div>
        </slot>
      </div>
    </div>

    <!-- 滚动到顶部按钮 -->
    <tui-button v-if="showToTopButton && !isAtTop" type="text" @click="handleScrollToTop" :class="{
      'tui-scrollbar--to-top-btn--visible': !isAtTop
    }" title="滚动到顶部">
      <slot name="toTopIcon">
        <tui-icon icon="tui:arrow-up" size="20" />
      </slot>
    </tui-button>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed, watch } from 'vue';
import { ensureUnit } from '../../strings';
import type { TuiScrollbarProps, ScrollInfo } from './types';

// 设置默认值
const props = withDefaults(defineProps<TuiScrollbarProps>(), {
  trackWidth: undefined, // 轨道宽度
  thumbWidth: undefined, // 滑块宽度
  widthSyncMode: 'auto',
  trackColor: '#f0f0f0',
  thumbColor: '#d9d9d9',
  thumbHoverColor: '#bfbfbf',
  borderRadius: 3,
  showOnlyWhenNeeded: true,
  height: '100%',
  maxHeight: 'none',
  width: '100%', // 容器宽度
  showHorizontal: true,
  showVertical: true,
  initialScrollTop: 0,
  showToTopButton: false,
  toTopThreshold: 300,
  visibilityMode: 'always', // 默认值为'always'，表示始终显示滚动条
  wheelHorizontal: 'auto', // 默认值为'auto'，表示自动判断是否进行水平滚动
  enableSmoothScroll: true, // 默认启用平滑滚动
  scrollFriction: 0.85, // 平滑滚动的摩擦系数
  scrollAcceleration: 1.5, // 平滑滚动的加速度系数
  scrollMinVelocity: 0.5, // 平滑滚动的最小速度阈值
  wheelSensitivity: 0.1 // 滚轮灵敏度（0.1-3，值越小滚动越不敏感，默认为1）
});

// 存储上一次的滚动位置，用于检测滚动方向
const prevScrollTop = ref(0);
const prevScrollLeft = ref(0);

// 滚动方向状态
const scrollDirection = ref<{ vertical: 'up' | 'down' | 'none', horizontal: 'left' | 'right' | 'none' }>({
  vertical: 'none',
  horizontal: 'none'
});

const emit = defineEmits<{
  (e: 'scroll', info: ScrollInfo): void;
  (e: 'scroll-to-top'): void;
  (e: 'scroll-to-bottom'): void;
  (e: 'scroll-start'): void;
  (e: 'scroll-end'): void;
}>();

// 元素引用
const scrollContainer = ref<HTMLDivElement>();
const verticalTrack = ref<HTMLDivElement>();
const verticalThumb = ref<HTMLDivElement>();
const horizontalTrack = ref<HTMLDivElement>();
const horizontalThumb = ref<HTMLDivElement>();

// 状态管理
const isScrolling = ref(false);
const scrollTimeout = ref<number | null>(null);
const isAtTop = ref(true);
const isAtBottom = ref(false);
const isDraggingVertical = ref(false);
const isDraggingHorizontal = ref(false);
const verticalThumbColor = ref(props.thumbColor);
const horizontalThumbColor = ref(props.thumbColor);
// 拖拽状态相关
const dragStartY = ref(0);
const dragStartX = ref(0);
const startScrollTop = ref(0);
const startScrollLeft = ref(0);

// 滚动信息
const scrollInfo = ref<ScrollInfo>({
  top: 0,
  left: 0,
  height: 0,
  width: 0,
  clientHeight: 0,
  clientWidth: 0,
  isAtTop: true,
  isAtBottom: false
});

// 计算属性 - 处理轨道宽度和滑块宽度的同步逻辑
const effectiveTrackWidth = computed(() => {
  // 优先使用trackWidth
  if (props.trackWidth !== undefined) {
    return props.trackWidth;
  }

  // 如果同步模式为auto，且没有设置trackWidth但设置了thumbWidth，则使用thumbWidth
  if (props.widthSyncMode === 'auto' && props.thumbWidth !== undefined) {
    return props.thumbWidth;
  }

  // 使用默认值
  return 10;
});

const effectiveThumbWidth = computed(() => {
  // 优先使用thumbWidth
  if (props.thumbWidth !== undefined) {
    return props.thumbWidth;
  }

  // 如果同步模式为auto，且没有设置thumbWidth但设置了trackWidth，则使用trackWidth
  if (props.widthSyncMode === 'auto' && props.trackWidth !== undefined) {
    return props.trackWidth;
  }

  // 使用默认值
  return 6;
});

// 计算属性 - 容器样式
const containerStyle = computed(() => ({
  height: ensureUnit(props.height, 'px'),
  width: ensureUnit(props.width, 'px'),
  maxHeight: props.maxHeight !== 'none' ? ensureUnit(props.maxHeight, 'px') : 'none',
  position: 'relative',
  // overflow: 'hidden'
}));

// 计算属性 - 滚动容器样式
const scrollContainerStyle = computed(() => ({
  height: containerStyle.value.height,
  width: containerStyle.value.width,
  // overflow: 'auto',
  // 隐藏原生滚动条
  scrollbarWidth: 'none', // Firefox
  msOverflowStyle: 'none', // IE 10+ 
}));

// 计算属性 - 内容区域padding样式
const contentPaddingStyle = computed(() => {
  const styles: Record<string, string> = {};

  // 计算垂直滚动条的padding
  // 只有在组件配置显示垂直滚动条且内容实际需要垂直滚动条时才添加右侧padding
  if (props.showVertical && needVerticalScrollbar && scrollInfo.value.height > scrollInfo.value.clientHeight) {
    // 取轨道宽度和滑块宽度中的较大值
    const verticalPaddingWidth = Math.max(effectiveTrackWidth.value, effectiveThumbWidth.value);
    styles.paddingRight = ensureUnit(verticalPaddingWidth, 'px');
  }

  // 计算水平滚动条的padding
  // 只有在组件配置显示水平滚动条且内容实际需要水平滚动条时才添加底部padding
  if (props.showHorizontal && needHorizontalScrollbar && scrollInfo.value.width > scrollInfo.value.clientWidth) {
    // 取轨道宽度和滑块宽度中的较大值
    const horizontalPaddingHeight = Math.max(effectiveTrackWidth.value, effectiveThumbWidth.value);
    styles.paddingBottom = ensureUnit(horizontalPaddingHeight, 'px');
  }

  return styles;
});

// 计算是否需要显示垂直滚动条 - 使用响应式数据
const needVerticalScrollbar = computed(() => {
  // 从响应式数据scrollInfo获取所需信息，而不是直接依赖DOM元素
  const { height, clientHeight } = scrollInfo.value;
  return !props.showOnlyWhenNeeded || height > clientHeight;
});

// 计算是否需要显示水平滚动条 - 使用响应式数据
const needHorizontalScrollbar = computed(() => {
  // 从响应式数据scrollInfo获取所需信息，而不是直接依赖DOM元素
  const { width, clientWidth } = scrollInfo.value;
  return !props.showOnlyWhenNeeded || width > clientWidth;
});

// 计算垂直滚动条滑块高度 - 支持自定义插槽和默认两种模式
const verticalThumbHeight = computed(() => {
  // 如果使用了自定义垂直滑块插槽，直接设置为auto
  if (verticalThumb.value && verticalThumb.value.children.length > 0) {
    // 检查是否所有子元素都是默认的thumb-inner
    const hasCustomContent = Array.from(verticalThumb.value.children).some(child =>
      !child.classList?.contains('tui-scrollbar__thumb-inner')
    );

    if (hasCustomContent) {
      return 'auto';
    }
  }

  // 传统滚动条模式 - 根据内容计算
  const { height, clientHeight } = scrollInfo.value;
  if (height <= clientHeight) return '0px';

  // 计算滑块高度：可视区域高度 / 内容总高度 * 可视区域高度
  const thumbHeight = Math.max(30, (clientHeight / height) * clientHeight);
  return `${thumbHeight}px`;
});

// 计算垂直滚动条滑块位置 - 使用响应式数据scrollInfo
const verticalThumbTop = computed(() => {
  // 从响应式数据scrollInfo获取所需信息，而不是直接依赖DOM元素
  const { top, height, clientHeight } = scrollInfo.value;
  if (height <= clientHeight) return '0px';

  // 计算滑块位置：滚动距离 / (内容总高度 - 可视区域高度) * (可视区域高度 - 滑块高度)
  const scrollableHeight = height - clientHeight;
  if (scrollableHeight <= 0) return '0px';

  const ratio = top / scrollableHeight;
  let thumbHeight: number;

  // 检查是否使用了自定义垂直滑块插槽
  if (verticalThumb.value && verticalThumb.value.children.length > 0) {
    // 检查是否所有子元素都是默认的thumb-inner
    const hasCustomContent = Array.from(verticalThumb.value.children).some(child =>
      !child.classList?.contains('tui-scrollbar__thumb-inner')
    );

    if (hasCustomContent) {
      // 对于auto高度的自定义滑块，直接从DOM获取实际高度
      thumbHeight = verticalThumb.value.getBoundingClientRect().height;
    } else {
      // 传统滚动条模式
      thumbHeight = parseFloat(verticalThumbHeight.value);
    }
  } else {
    // 传统滚动条模式
    thumbHeight = parseFloat(verticalThumbHeight.value);
  }

  const maxTop = clientHeight - thumbHeight;
  const topValue = ratio * maxTop;

  // 确保滑块位置在有效范围内
  return `${Math.max(0, Math.min(maxTop, topValue))}px`;
});

// 计算水平滚动条滑块宽度 - 支持自定义插槽和默认两种模式
const horizontalThumbWidth = computed(() => {
  // 如果使用了自定义水平滑块插槽，直接设置为auto
  if (horizontalThumb.value && horizontalThumb.value.children.length > 0) {
    // 检查是否所有子元素都是默认的thumb-inner
    const hasCustomContent = Array.from(horizontalThumb.value.children).some(child =>
      !child.classList?.contains('tui-scrollbar__thumb-inner')
    );

    if (hasCustomContent) {
      return 'auto';
    }
  }

  // 传统滚动条模式 - 根据内容计算
  const { width, clientWidth } = scrollInfo.value;
  if (width <= clientWidth) return '0px';

  // 计算滑块宽度：可视区域宽度 / 内容总宽度 * 可视区域宽度
  const thumbWidth = Math.max(30, (clientWidth / width) * clientWidth);
  return `${thumbWidth}px`;
});

// 计算水平滚动条滑块位置 - 使用响应式数据scrollInfo
const horizontalThumbLeft = computed(() => {
  // 从响应式数据scrollInfo获取所需信息，而不是直接依赖DOM元素
  const { left, width, clientWidth } = scrollInfo.value;
  if (width <= clientWidth) return '0px';

  // 计算滑块位置：滚动距离 / (内容总宽度 - 可视区域宽度) * (可视区域宽度 - 滑块宽度)
  const scrollableWidth = width - clientWidth;
  if (scrollableWidth <= 0) return '0px';

  const ratio = left / scrollableWidth;
  let thumbWidth: number;

  // 检查是否使用了自定义水平滑块插槽
  if (horizontalThumb.value && horizontalThumb.value.children.length > 0) {
    // 检查是否所有子元素都是默认的thumb-inner
    const hasCustomContent = Array.from(horizontalThumb.value.children).some(child =>
      !child.classList?.contains('tui-scrollbar__thumb-inner')
    );

    if (hasCustomContent) {
      // 对于auto宽度的自定义滑块，直接从DOM获取实际宽度
      thumbWidth = horizontalThumb.value.getBoundingClientRect().width;
    } else {
      // 传统滚动条模式
      thumbWidth = parseFloat(horizontalThumbWidth.value);
    }
  } else {
    // 传统滚动条模式
    thumbWidth = parseFloat(horizontalThumbWidth.value);
  }

  const maxLeft = clientWidth - thumbWidth;
  const leftValue = ratio * maxLeft;

  // 确保滑块位置在有效范围内
  return `${Math.max(0, Math.min(maxLeft, leftValue))}px`;
});

// 计算垂直滚动进度（0-1之间的值）
const verticalScrollProgress = computed(() => {
  const { top, height, clientHeight } = scrollInfo.value;
  const scrollableHeight = height - clientHeight;
  if (scrollableHeight <= 0) return 0;
  return Math.max(0, Math.min(1, top / scrollableHeight));
});

// 计算水平滚动进度（0-1之间的值）
const horizontalScrollProgress = computed(() => {
  const { left, width, clientWidth } = scrollInfo.value;
  const scrollableWidth = width - clientWidth;
  if (scrollableWidth <= 0) return 0;
  return Math.max(0, Math.min(1, left / scrollableWidth));
});

// 处理滚动事件
const handleScroll = () => {
  if (!scrollContainer.value) return;

  const element = scrollContainer.value;
  const newScrollInfo = {
    top: element.scrollTop,
    left: element.scrollLeft,
    height: element.scrollHeight,
    width: element.scrollWidth,
    clientHeight: element.clientHeight,
    clientWidth: element.clientWidth,
    isAtTop: element.scrollTop === 0,
    isAtBottom: element.scrollTop + element.clientHeight >= element.scrollHeight - 1
  };

  // 计算滚动方向 - 只在有滚动变化时更新方向，保持最后一次的滚动方向
  // 垂直方向
  if (element.scrollTop > prevScrollTop.value) {
    scrollDirection.value.vertical = 'down';
  } else if (element.scrollTop < prevScrollTop.value) {
    scrollDirection.value.vertical = 'up';
  }
  // 注意：当scrollTop没有变化时，不更新方向，保持原来的值

  // 水平方向
  if (element.scrollLeft > prevScrollLeft.value) {
    scrollDirection.value.horizontal = 'right';
  } else if (element.scrollLeft < prevScrollLeft.value) {
    scrollDirection.value.horizontal = 'left';
  }
  // 注意：当scrollLeft没有变化时，不更新方向，保持原来的值

  // 更新上一次的滚动位置
  prevScrollTop.value = element.scrollTop;
  prevScrollLeft.value = element.scrollLeft;

  // 更新状态
  isAtTop.value = newScrollInfo.isAtTop;
  isAtBottom.value = newScrollInfo.isAtBottom;
  scrollInfo.value = newScrollInfo;

  // 触发滚动事件
  emit('scroll', newScrollInfo);

  // 触发滚动开始事件
  if (!isScrolling.value) {
    isScrolling.value = true;
    emit('scroll-start');
  }

  // 清除之前的定时器
  if (scrollTimeout.value) {
    clearTimeout(scrollTimeout.value);
  }

  // 设置新的定时器来检测滚动结束
  scrollTimeout.value = window.setTimeout(() => {
    isScrolling.value = false;
    emit('scroll-end');
  }, 150);

  // 触发滚动到底部事件
  if (newScrollInfo.isAtBottom && !isAtBottom.value) {
    emit('scroll-to-bottom');
  }
};

// 处理滑块拖拽开始
const handleThumbMouseDown = (direction: 'vertical' | 'horizontal') => {
  if (!scrollContainer.value) return;

  const container = scrollContainer.value;
  const event = window.event as MouseEvent;

  if (direction === 'vertical') {
    isDraggingVertical.value = true;
    // 记录初始拖动状态
    dragStartY.value = event.clientY;
    startScrollTop.value = container.scrollTop;
  } else {
    isDraggingHorizontal.value = true;
    // 记录初始拖动状态
    dragStartX.value = event.clientX;
    startScrollLeft.value = container.scrollLeft;
  }

  // 阻止文本选择
  document.addEventListener('selectstart', preventSelect);
  document.addEventListener('dragstart', preventSelect);

  // 阻止默认行为
  event.preventDefault();
};

// 处理轨道点击
const handleTrackMouseDown = (direction: 'vertical' | 'horizontal') => {
  if (!scrollContainer.value) return;

  const container = scrollContainer.value;
  const track = direction === 'vertical' ? verticalTrack.value : horizontalTrack.value;

  if (!track) return;

  // 获取点击位置
  const rect = track.getBoundingClientRect();
  const clickEvent = window.event as MouseEvent;
  const clickPos = direction === 'vertical'
    ? clickEvent.clientY - rect.top
    : clickEvent.clientX - rect.left;

  // 获取滑块尺寸
  let thumbSize: number;

  // 检查是否使用了自定义插槽
  if (direction === 'vertical' && verticalThumb.value && verticalThumb.value.children.length > 0) {
    // 检查是否所有子元素都是默认的thumb-inner
    const hasCustomContent = Array.from(verticalThumb.value.children).some(child =>
      !child.classList?.contains('tui-scrollbar__thumb-inner')
    );

    if (hasCustomContent) {
      // 对于auto高度的自定义垂直滑块，直接从DOM获取实际高度
      thumbSize = verticalThumb.value.getBoundingClientRect().height;
    } else {
      // 传统滚动条模式
      thumbSize = parseFloat(verticalThumbHeight.value);
    }
  } else if (direction === 'horizontal' && horizontalThumb.value && horizontalThumb.value.children.length > 0) {
    // 检查是否所有子元素都是默认的thumb-inner
    const hasCustomContent = Array.from(horizontalThumb.value.children).some(child =>
      !child.classList?.contains('tui-scrollbar__thumb-inner')
    );

    if (hasCustomContent) {
      // 对于auto宽度的自定义水平滑块，直接从DOM获取实际宽度
      thumbSize = horizontalThumb.value.getBoundingClientRect().width;
    } else {
      // 传统滚动条模式
      thumbSize = parseFloat(horizontalThumbWidth.value);
    }
  } else {
    // 传统滚动条模式
    thumbSize = direction === 'vertical'
      ? parseFloat(verticalThumbHeight.value)
      : parseFloat(horizontalThumbWidth.value);
  }

  // 获取容器尺寸和内容尺寸
  const clientSize = direction === 'vertical' ? container.clientHeight : container.clientWidth;
  const scrollSize = direction === 'vertical' ? container.scrollHeight : container.scrollWidth;

  // 计算点击位置对应的滚动位置
  // 减去滑块一半高度，使点击位置对应滑块中心
  const targetRatio = (clickPos - thumbSize / 2) / (clientSize - thumbSize);
  const scrollToPos = Math.max(0, Math.min(
    scrollSize - clientSize,
    targetRatio * (scrollSize - clientSize)
  ));

  // 滚动到目标位置
  if (direction === 'vertical') {
    container.scrollTop = scrollToPos;
  } else {
    container.scrollLeft = scrollToPos;
  }
};

// 处理鼠标移动事件 - 用于拖拽
const handleMouseMove = (event: MouseEvent) => {
  if (!scrollContainer.value) return;

  const container = scrollContainer.value;

  // 垂直滚动条拖拽
  if (isDraggingVertical.value && verticalTrack.value) {
    // 计算鼠标相对于初始位置的Y轴偏移量
    const deltaY = event.clientY - dragStartY.value;
    const clientHeight = container.clientHeight;
    const scrollHeight = container.scrollHeight;

    // 检查是否使用了自定义垂直滑块插槽
    let scrollToPos: number;

    // 自定义插槽模式 - 直接根据鼠标偏移量和轨道高度比例计算
    if (verticalThumb.value && verticalThumb.value.children.length > 0) {
      // 检查是否所有子元素都是默认的thumb-inner
      const hasCustomContent = Array.from(verticalThumb.value.children).some(child =>
        !child.classList?.contains('tui-scrollbar__thumb-inner')
      );

      if (hasCustomContent) {
        // 获取轨道高度
        const trackHeight = verticalTrack.value.clientHeight;
        // 对于auto高度的自定义滑块，直接从DOM获取实际高度
        const thumbHeight = verticalThumb.value.getBoundingClientRect().height;
        // 计算轨道可滚动区域高度
        const trackScrollableHeight = trackHeight - thumbHeight;
        // 计算鼠标偏移量占可滚动区域的比例
        const deltaRatio = deltaY / trackScrollableHeight;
        // 根据比例计算内容应该滚动的距离
        scrollToPos = Math.max(0, Math.min(
          scrollHeight - clientHeight,
          startScrollTop.value + (deltaRatio * (scrollHeight - clientHeight))
        ));
      } else {
        // 传统滚动条模式 - 根据偏移量和容器高度比例计算新的滚动位置
        const thumbHeight = parseFloat(verticalThumbHeight.value);
        // 公式: 初始滚动位置 + (鼠标偏移量 / (可视高度 - 滑块高度)) * (内容高度 - 可视高度)
        const scrollRatio = deltaY / (clientHeight - thumbHeight);
        const scrollDelta = scrollRatio * (scrollHeight - clientHeight);
        scrollToPos = Math.max(0, Math.min(
          scrollHeight - clientHeight,
          startScrollTop.value + scrollDelta
        ));
      }
    } else {
      // 传统滚动条模式 - 根据偏移量和容器高度比例计算新的滚动位置
      const thumbHeight = parseFloat(verticalThumbHeight.value);
      // 公式: 初始滚动位置 + (鼠标偏移量 / (可视高度 - 滑块高度)) * (内容高度 - 可视高度)
      const scrollRatio = deltaY / (clientHeight - thumbHeight);
      const scrollDelta = scrollRatio * (scrollHeight - clientHeight);
      scrollToPos = Math.max(0, Math.min(
        scrollHeight - clientHeight,
        startScrollTop.value + scrollDelta
      ));
    }

    container.scrollTop = scrollToPos;
  }

  // 水平滚动条拖拽
  if (isDraggingHorizontal.value && horizontalTrack.value) {
    // 计算鼠标相对于初始位置的X轴偏移量
    const deltaX = event.clientX - dragStartX.value;
    const clientWidth = container.clientWidth;
    const scrollWidth = container.scrollWidth;

    // 检查是否使用了自定义水平滑块插槽
    let scrollToPos: number;

    // 自定义插槽模式 - 直接根据鼠标偏移量和轨道宽度比例计算
    if (horizontalThumb.value && horizontalThumb.value.children.length > 0) {
      // 检查是否所有子元素都是默认的thumb-inner
      const hasCustomContent = Array.from(horizontalThumb.value.children).some(child =>
        !child.classList?.contains('tui-scrollbar__thumb-inner')
      );

      if (hasCustomContent) {
        // 获取轨道宽度
        const trackWidth = horizontalTrack.value.clientWidth;
        // 对于auto宽度的自定义滑块，直接从DOM获取实际宽度
        const thumbWidth = horizontalThumb.value.getBoundingClientRect().width;
        // 计算轨道可滚动区域宽度
        const trackScrollableWidth = trackWidth - thumbWidth;
        // 计算鼠标偏移量占可滚动区域的比例
        const deltaRatio = deltaX / trackScrollableWidth;
        // 根据比例计算内容应该滚动的距离
        scrollToPos = Math.max(0, Math.min(
          scrollWidth - clientWidth,
          startScrollLeft.value + (deltaRatio * (scrollWidth - clientWidth))
        ));
      } else {
        // 传统滚动条模式 - 根据偏移量和容器宽度比例计算新的滚动位置
        const thumbWidth = parseFloat(horizontalThumbWidth.value);
        // 公式: 初始滚动位置 + (鼠标偏移量 / (可视宽度 - 滑块宽度)) * (内容宽度 - 可视宽度)
        const scrollRatio = deltaX / (clientWidth - thumbWidth);
        const scrollDelta = scrollRatio * (scrollWidth - clientWidth);
        scrollToPos = Math.max(0, Math.min(
          scrollWidth - clientWidth,
          startScrollLeft.value + scrollDelta
        ));
      }
    } else {
      // 传统滚动条模式 - 根据偏移量和容器宽度比例计算新的滚动位置
      const thumbWidth = parseFloat(horizontalThumbWidth.value);
      // 公式: 初始滚动位置 + (鼠标偏移量 / (可视宽度 - 滑块宽度)) * (内容宽度 - 可视宽度)
      const scrollRatio = deltaX / (clientWidth - thumbWidth);
      const scrollDelta = scrollRatio * (scrollWidth - clientWidth);
      scrollToPos = Math.max(0, Math.min(
        scrollWidth - clientWidth,
        startScrollLeft.value + scrollDelta
      ));
    }

    container.scrollLeft = scrollToPos;
  }
};

// 处理鼠标释放事件 - 结束拖拽
const handleMouseUp = () => {
  if (isDraggingVertical.value || isDraggingHorizontal.value) {
    isDraggingVertical.value = false;
    isDraggingHorizontal.value = false;

    // 移除文本选择阻止
    document.removeEventListener('selectstart', preventSelect);
    document.removeEventListener('dragstart', preventSelect);
  }
};

// 阻止文本选择
const preventSelect = (event: Event) => {
  event.preventDefault();
  return false;
};

// 处理滚动条滑块悬停
const handleThumbMouseEnter = (direction: 'vertical' | 'horizontal') => {
  if (direction === 'vertical') {
    verticalThumbColor.value = props.thumbHoverColor;
  } else {
    horizontalThumbColor.value = props.thumbHoverColor;
  }
};

// 处理滚动条滑块离开悬停
const handleThumbMouseLeave = (direction: 'vertical' | 'horizontal') => {
  if (direction === 'vertical') {
    verticalThumbColor.value = props.thumbColor;
  } else {
    horizontalThumbColor.value = props.thumbColor;
  }
};

// 处理滚动到顶部按钮点击事件
const handleScrollToTop = (event: MouseEvent) => {
  event.preventDefault();
  scrollToTop(true);
};

// 滚动到顶部
const scrollToTop = (smooth: boolean = true) => {
  if (!scrollContainer.value) return;

  scrollContainer.value.scrollTo({
    top: 0,
    behavior: smooth ? 'smooth' : 'auto'
  });

  emit('scroll-to-top');
};

// 滚动到底部
const scrollToBottom = (smooth: boolean = true) => {
  if (!scrollContainer.value) return;

  scrollContainer.value.scrollTo({
    top: scrollContainer.value.scrollHeight - scrollContainer.value.clientHeight,
    behavior: smooth ? 'smooth' : 'auto'
  });
};

// 滚动到指定位置
const scrollTo = (position: { top?: number; left?: number }, smooth: boolean = true) => {
  if (!scrollContainer.value) return;

  scrollContainer.value.scrollTo({
    ...position,
    behavior: smooth ? 'smooth' : 'auto'
  });
};

// 获取滚动信息
const getScrollInfo = (): ScrollInfo => {
  return { ...scrollInfo.value };
};

// 平滑滚动相关状态
// 水平滚动
const scrollVelocity = ref(0);
const isSmoothScrolling = ref(false);
// 垂直滚动
const verticalScrollVelocity = ref(0);
const isSmoothVerticalScrolling = ref(false);
// 共用时间戳
const lastScrollTime = ref(0);

// 处理鼠标滚轮事件 - 支持水平滚动和垂直滚动
const handleWheel = (event: WheelEvent) => {
  if (!scrollContainer.value) return;

  const container = scrollContainer.value;
  const hasHorizontalScrollbar = container.scrollWidth > container.clientWidth && props.showHorizontal;
  const hasVerticalScrollbar = container.scrollHeight > container.clientHeight && props.showVertical;

  // 检查是否需要进行水平滚动
  // 1. 当wheelHorizontal为'shift'时，需要按下Shift键
  // 2. 当wheelHorizontal为'auto'时，只要存在水平滚动条就直接水平滚动
  // 3. 也处理天然的水平滚轮事件（如触摸板横向滚动）
  const shouldHorizontalScroll = hasHorizontalScrollbar &&
    ((props.wheelHorizontal === 'shift' && event.shiftKey) ||
      (props.wheelHorizontal === 'auto') ||
      Math.abs(event.deltaX) > Math.abs(event.deltaY * 0.5));

  // 检查是否需要进行垂直滚动
  const shouldVerticalScroll = hasVerticalScrollbar && !shouldHorizontalScroll;

  if (shouldHorizontalScroll) {
    event.preventDefault(); // 阻止默认的垂直滚动行为

    // 计算水平滚动距离（反转滚动方向，并应用滚轮灵敏度）
    const deltaRaw = Math.abs(event.deltaX) > Math.abs(event.deltaY * 0.5)
      ? -event.deltaX // 反转水平滚动方向
      : event.deltaY; // 反转垂直滚轮映射的水平滚动方向

    // 应用滚轮灵敏度，值越小滚动越不敏感
    const delta = deltaRaw * props.wheelSensitivity;

    if (props.enableSmoothScroll) {
      // 平滑滚动实现
      const currentTime = Date.now();
      const timeDiff = currentTime - lastScrollTime.value;
      lastScrollTime.value = currentTime;

      // 更新滚动速度（考虑加速度）
      const speedMultiplier = timeDiff < 16 ? props.scrollAcceleration : 1; // 更快的连续滚动提供更多加速度
      scrollVelocity.value = (scrollVelocity.value * 0.7 + delta * props.scrollAcceleration * speedMultiplier) * props.scrollFriction; // 衰减因子

      // 如果不是平滑滚动状态，启动平滑滚动动画
      if (!isSmoothScrolling.value) {
        isSmoothScrolling.value = true;
        smoothScrollAnimation();
      }
    } else {
      // 非平滑滚动模式
      container.scrollLeft += delta * props.scrollAcceleration;
    }

    // 触发滚动事件
    handleScroll();
  } else if (shouldVerticalScroll) {
    event.preventDefault(); // 阻止默认的垂直滚动行为

    // 计算垂直滚动距离（应用滚轮灵敏度）
    const delta = event.deltaY * props.wheelSensitivity;

    if (props.enableSmoothScroll) {
      // 平滑滚动实现
      const currentTime = Date.now();
      const timeDiff = currentTime - lastScrollTime.value;
      lastScrollTime.value = currentTime;

      // 更新滚动速度（考虑加速度）
      const speedMultiplier = timeDiff < 16 ? props.scrollAcceleration : 1; // 更快的连续滚动提供更多加速度
      verticalScrollVelocity.value = (verticalScrollVelocity.value * 0.7 + delta * props.scrollAcceleration * speedMultiplier) * props.scrollFriction; // 衰减因子

      // 如果不是平滑滚动状态，启动平滑滚动动画
      if (!isSmoothVerticalScrolling.value) {
        isSmoothVerticalScrolling.value = true;
        smoothVerticalScrollAnimation();
      }
    } else {
      // 非平滑滚动模式
      container.scrollTop += delta * props.scrollAcceleration;
    }

    // 触发滚动事件
    handleScroll();
  }
};

// 水平平滑滚动动画函数
const smoothScrollAnimation = () => {
  if (!scrollContainer.value || Math.abs(scrollVelocity.value) < props.scrollMinVelocity) {
    isSmoothScrolling.value = false;
    scrollVelocity.value = 0;
    return;
  }

  const container = scrollContainer.value;

  // 应用当前速度并逐渐衰减
  container.scrollLeft += scrollVelocity.value;
  scrollVelocity.value *= props.scrollFriction; // 滚动衰减因子

  // 确保不超出滚动范围
  const maxScrollLeft = container.scrollWidth - container.clientWidth;
  container.scrollLeft = Math.max(0, Math.min(maxScrollLeft, container.scrollLeft));

  // 继续动画
  requestAnimationFrame(smoothScrollAnimation);

  // 触发滚动事件
  handleScroll();
};

// 垂直平滑滚动动画函数
const smoothVerticalScrollAnimation = () => {
  if (!scrollContainer.value || Math.abs(verticalScrollVelocity.value) < props.scrollMinVelocity) {
    isSmoothVerticalScrolling.value = false;
    verticalScrollVelocity.value = 0;
    return;
  }

  const container = scrollContainer.value;

  // 应用当前速度并逐渐衰减
  container.scrollTop += verticalScrollVelocity.value;
  verticalScrollVelocity.value *= props.scrollFriction; // 滚动衰减因子

  // 确保不超出滚动范围
  const maxScrollTop = container.scrollHeight - container.clientHeight;
  container.scrollTop = Math.max(0, Math.min(maxScrollTop, container.scrollTop));

  // 继续动画
  requestAnimationFrame(smoothVerticalScrollAnimation);

  // 触发滚动事件
  handleScroll();
};

// 生命周期钩子
onMounted(() => {
  if (!scrollContainer.value) return;

  // 设置初始滚动位置
  if (props.initialScrollTop > 0) {
    scrollContainer.value.scrollTop = props.initialScrollTop;
    handleScroll(); // 手动触发一次滚动事件以更新状态
  }

  // 添加滚动事件监听
  scrollContainer.value.addEventListener('scroll', handleScroll, { passive: true });

  // 添加鼠标滚轮事件监听，passive设为false以便能阻止默认行为
  scrollContainer.value.addEventListener('wheel', handleWheel, { passive: false });

  // 添加全局鼠标事件监听
  document.addEventListener('mousemove', handleMouseMove);
  document.addEventListener('mouseup', handleMouseUp);

  // 添加滑块悬停事件监听
  if (verticalThumb.value) {
    verticalThumb.value.addEventListener('mouseenter', () => handleThumbMouseEnter('vertical'));
    verticalThumb.value.addEventListener('mouseleave', () => handleThumbMouseLeave('vertical'));
  }

  if (horizontalThumb.value) {
    horizontalThumb.value.addEventListener('mouseenter', () => handleThumbMouseEnter('horizontal'));
    horizontalThumb.value.addEventListener('mouseleave', () => handleThumbMouseLeave('horizontal'));
  }

  // 监听内容变化，处理动态内容导致的滚动条更新
  const resizeObserver = new ResizeObserver(() => {
    // 强制重新计算计算属性
    if (scrollContainer.value) {
      // 对于自定义插槽滚动条，需要特殊处理来确保正确更新
      if ((verticalThumb.value && verticalThumb.value.children.length > 0) ||
        (horizontalThumb.value && horizontalThumb.value.children.length > 0)) {
        // 强制重新渲染计算属性
        const tempScrollInfo = { ...scrollInfo.value };
        scrollInfo.value = { ...tempScrollInfo };
      }

      // 触发一次滚动事件以更新所有状态
      handleScroll();
    }
  });

  if (scrollContainer.value) {
    resizeObserver.observe(scrollContainer.value);
  }

  // 存储resizeObserver以便在卸载时清理
  (scrollContainer.value as any)._resizeObserver = resizeObserver;
});

onUnmounted(() => {
  // 清除定时器
  if (scrollTimeout.value) {
    clearTimeout(scrollTimeout.value);
  }

  // 移除滚动事件监听
  if (scrollContainer.value) {
    scrollContainer.value.removeEventListener('scroll', handleScroll);
    // 移除鼠标滚轮事件监听
    scrollContainer.value.removeEventListener('wheel', handleWheel);
  }

  // 移除全局鼠标事件监听
  document.removeEventListener('mousemove', handleMouseMove);
  document.removeEventListener('mouseup', handleMouseUp);
  document.removeEventListener('selectstart', preventSelect);
  document.removeEventListener('dragstart', preventSelect);

  // 移除滑块悬停事件监听
  if (verticalThumb.value) {
    verticalThumb.value.removeEventListener('mouseenter', () => handleThumbMouseEnter('vertical'));
    verticalThumb.value.removeEventListener('mouseleave', () => handleThumbMouseLeave('vertical'));
  }

  if (horizontalThumb.value) {
    horizontalThumb.value.removeEventListener('mouseenter', () => handleThumbMouseEnter('horizontal'));
    horizontalThumb.value.removeEventListener('mouseleave', () => handleThumbMouseLeave('horizontal'));
  }

  // 清理ResizeObserver
  if (scrollContainer.value && (scrollContainer.value as any)._resizeObserver) {
    (scrollContainer.value as any)._resizeObserver.disconnect();
  }
});

// 暴露方法给父组件
defineExpose({
  scrollToTop,
  scrollToBottom,
  scrollTo,
  getScrollInfo
});
</script>

<style scoped>
/* 滚动条容器 */
.tui-scrollbar {
  display: inline-block;
  position: relative;
  box-sizing: border-box;
  /* overflow: hidden; */
}

/* 滚动内容容器 */
.tui-scrollbar__container {
  position: relative;
  box-sizing: border-box;
  overflow: auto;
  width: 100%;
  height: 100%;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

/* 隐藏Webkit原生滚动条 */
.tui-scrollbar__container::-webkit-scrollbar {
  display: none;
}

/* 滚动内容 */
.tui-scrollbar__content {
  min-height: 100%;
  min-width: 100%;
  box-sizing: border-box;
}

/* 滚动条轨道 - 垂直 */
.tui-scrollbar__track--vertical {
  position: absolute;
  top: 0;
  right: 0;
  /* 宽度通过内联样式动态设置 */
  height: 100%;
  border-radius: 5px;
  opacity: 0;
  transition: opacity 0.2s ease;
  cursor: pointer;
  z-index: 5;
}

/* 滚动条轨道 - 水平 */
.tui-scrollbar__track--horizontal {
  position: absolute;
  bottom: 0;
  left: 0;
  /* 高度通过内联样式动态设置 */
  width: 100%;
  border-radius: 5px;
  opacity: 0;
  transition: opacity 0.2s ease;
  cursor: pointer;
  z-index: 5;
}

/* 滚动条容器悬停时显示轨道 */
.tui-scrollbar:hover .tui-scrollbar__track {
  opacity: 1;
}

/* 当设置为始终显示模式时，滚动条轨道始终可见 */
.tui-scrollbar--always-visible .tui-scrollbar__track {
  opacity: 1;
}

/* 滚动条滑块 - 垂直 */
.tui-scrollbar__thumb--vertical {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  border-radius: 3px;
  cursor: grab;
  transition: background-color 0.2s ease;
  user-select: none;
  -webkit-user-select: none;
  z-index: 6;
}

/* 滚动条滑块 - 水平 */
.tui-scrollbar__thumb--horizontal {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  border-radius: 3px;
  cursor: grab;
  transition: background-color 0.2s ease;
  user-select: none;
  -webkit-user-select: none;
  z-index: 6;
}

/* 滑块拖拽时样式 */
.tui-scrollbar__thumb--vertical:active,
.tui-scrollbar__thumb--horizontal:active {
  cursor: grabbing;
}

/* 滚动到顶部按钮 */
.tui-scrollbar__to-top-btn {
  position: absolute;
  bottom: 20px;
  right: 20px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  border: none;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

/* 滚动到顶部按钮可见状态 */
.tui-scrollbar__to-top-btn--visible {
  opacity: 1;
}

/* 滚动到顶部按钮悬停状态 */
.tui-scrollbar__to-top-btn:hover {
  background-color: rgba(0, 0, 0, 0.7);
}

/* 滚动到顶部按钮图标 */
.tui-scrollbar__to-top-btn svg {
  width: 20px;
  height: 20px;
}

/* 为了支持IE11等旧浏览器，添加一些兼容性样式 */
@media screen and (-ms-high-contrast: active),
(-ms-high-contrast: none) {

  /* IE11滚动条容器样式 */
  .tui-scrollbar__container {
    -ms-overflow-style: none;
  }
}
</style>